#include "PlayerModel.h"
#include "BasePlayer.h"
#include "GraphicManager.h"
#include "Team.h"
#include "Params.h"


using namespace std;

PlayerModel::PlayerModel(BasePlayer* owner) : Model("Player"),
												m_owner(owner),
												m_frame(0)
{

	if(m_owner->GetTeam()->Color() == Params::blue){
		SetPlayerShortsTextureID(GraphicManager::Istance()->GetTexture("uniform-blue"));
		SetPlayerUniformTextureID(GraphicManager::Istance()->GetTexture("uniform-blue"));
	}

	m_anim = GraphicManager::Istance()->GetAnim("PlayerWalk");

}

PlayerModel::~PlayerModel()
{

}

void PlayerModel::RenderSkele()
{
	for (int i = 0; i < m_anim.BonesCount; ++i)
	{
		if (i != 0)
		{
			glColor3f(0.f,1.f,0.f);
			glBegin(GL_LINES);
				glVertex3f( m_anim.Frames[m_frame].Skeleton[m_anim.Frames[m_frame].Skeleton[i].ParentBone].GlobalPosition[0][3], 
							m_anim.Frames[m_frame].Skeleton[m_anim.Frames[m_frame].Skeleton[i].ParentBone].GlobalPosition[1][3],
							m_anim.Frames[m_frame].Skeleton[m_anim.Frames[m_frame].Skeleton[i].ParentBone].GlobalPosition[2][3]);
				glVertex3f( m_anim.Frames[m_frame].Skeleton[i].GlobalPosition[0][3],
							 m_anim.Frames[m_frame].Skeleton[i].GlobalPosition[1][3],
							  m_anim.Frames[m_frame].Skeleton[i].GlobalPosition[2][3]);
			glEnd();
		}
	}
}

void PlayerModel::RenderAura()
{
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, GraphicManager::Istance()->GetTexture("aura"));
	glBegin(GL_QUADS);
		glTexCoord2f(0.f,0.f);glVertex3f(-10.f,0.2f,-10.f);	//TOP-LEFT
		glTexCoord2f(0.f,1.f);glVertex3f(10.f,0.2f,-10.f);
		glTexCoord2f(1.f,1.f);glVertex3f(10.f,0.2f,10.f);
		glTexCoord2f(1.f,0.f);glVertex3f(-10.f,0.2f,10.f);
	glEnd();
	glDisable(GL_TEXTURE_2D);
}	

void PlayerModel::Draw(const sf::Vector2f& offset, const sf::Vector2f& facing)
{
	m_frame += 1;
	if(m_frame >= m_anim.FramesCount) m_frame = 0;

	glPushMatrix();

	//Identical(correct en?=P) Matrix
	GLfloat matrix[] = {1.f, 0.f, 0.f, 0.f, 
		0.f, 1.f, 0.f, 0.f, 
		0.f, 0.f, 1.f, 0.f, 
		0.f, 0.f, 0.f, 1.f};


	//rotation on Y
	matrix[0] = facing.y;
	matrix[10] = facing.y;		

	if (facing.x != 0.f)
	{
		matrix[2] = -facing.x;
		matrix[8] = facing.x;
	}

	//Traslation offset
	matrix[12] = offset.x;
	matrix[14] = offset.y;

	glMultMatrixf(matrix);

	if(m_owner->IsUserControlled()) RenderAura();

	glLineWidth(2.0f);
	glColor3f( 0.f,1.f,0.f );

	RenderSkele();

	glColor3f(1.f,1.f,1.f);

	glLineWidth(0.01f);
	glPolygonMode(GL_FRONT, GL_LINE);

	GLuint shader = GraphicManager::Istance()->GetShader("skin");
	glUseProgram(shader);

	glEnableVertexAttribArrayARB(6);
	glEnableVertexAttribArrayARB(7);

	Matrix * bones =  new Matrix[m_anim.BonesCount];

	for (int i = 0; i < m_anim.BonesCount ; ++i)
	{
		for(int c = 0; c < 4 ; ++c)
		{
			for (int r = 0; r < 4 ; ++r)
			{	
				bones[i][c][r] =  m_anim.Frames[m_frame].Skeleton[i].GlobalPosition[c][r];
			}
		}
	}

	glUniformMatrix4fvARB(glGetUniformLocationARB(shader, "skin"), m_anim.BonesCount, GL_TRUE, (float*) bones);

	
	for (int i = 0; i < m_Data->TotalMesh ; ++i)
	{
		glBindBufferARB( GL_ARRAY_BUFFER_ARB, VBOIDs[i].VerticeID );
		glVertexAttribPointerARB(6, 1, GL_INT, 0,sizeof(struct Vertex),(void*)(sizeof(float)*3));
		glVertexAttribPointerARB(7, 1, GL_FLOAT, 0,sizeof(struct Vertex),(void*)((sizeof(float)*3) + (sizeof(unsigned int))));

		RenderMesh(i, shader);
	}

	delete [] bones;

	glDisableVertexAttribArrayARB(6);
	glDisableVertexAttribArrayARB(7);
	glUseProgram(0);
	
	
	glPolygonMode(GL_FRONT, GL_FILL);

	glPopMatrix();
	
}